back to index.

Implementing Tags in piaine

Overview

Over the past 2ish weeks I spent some time and added tag support to piaine, my static site generator used to power this blog. I hadn't touched the code in the two months prior, and so the process of working through the new feature and fitting it in to the existing code started off very exploratory. I thought it would be useful to document how exactly I went about this.

#Tag Parsing

In this first commit, I created a TagParser. The TagParser is more or less just a copy of the generic text parser I use for the rest of the program, but tailored to just read for comma-separated tags. Looking back on it now, it would definitely be as easy to just implement the tag parsing in the original text parser, but my rationale at the time was, and I still stand behind it, that keeping the two separate functions in separate parsers gives me less to think about when calling each one. After implementing this, I did a small piece of plumbing and implemented the TagParser as a function in the PageConsumer class to return the tags of a given page as a list of strings.

#Sitewide Tags

Following on from this, the next commit used a list in the main program file that would hold all tags for all pages in the site. In the first commit, these weren't de-duplicated as they were added in, but once I had confirmed that all tags from each page were being added, it was a simple if block to ensure no duplicate tags were added.

As part of this, I decided to implement a subclass of my Variable class that would hold a list of strings rather than keeping the list as a single string that is processed and split every time it's examined.

#Final Steps

At this point, things became a lot less exploratory. With the codebase fresh in my head, and having regained my understanding of how the generator put things together, the final steps came a lot easier and cleaner than the earlier work. Now that there was a list of tags for the whole site, it was time to write some code to generate the tag indexes. This was a simple repurposing of the buildIndexFile function in Program.cs. The tag files would be generated the same as the index file and link to a new folder that lived beside /posts/ called /tags/. A quick check to ensure the folder existed before attempting to write files there, a safety feature I should add to the rest of the codebase now, and things worked perfectly.

I wanted to keep the option to not generate the site with tags if desired, so moved the tag generation features behind a flag passed at runtime so they only run when desired. As part of this refactoring, I created a second implementation of the buildIndexFile function that took a second argument, the list of tags, to include them as a tagcloud where the template indicates. This tagcloud location was another small DSL tag added to the template reader also. As of the current version, I don't check "static pages" for tags, my intention when including them was that they are something different, and the posts are the only ones that the tags apply to.

With that done, the process was complete. I had to update my template files to include for the new features, and a quick runthrough with my sample test site and everything worked. I have not yet updated my content already online to use tags, but that will probably be used first on my hobby blog found here.


Comment